<!DOCTYPE html>

<html lang="zh-CN">

<head>
    
    <title>springboot集成安全框架 - 塔纳托斯</title>
    <meta charset="UTF-8">
    <meta name="keywords" content="">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=5">
    
    

    <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" />
    <meta name="description" content="在java领域中有Spring Security和Apache Shiro等安全框架，本次记录中使用springboot来集成这两个框架 shiroshiro比spring security更轻量，功能更简单些 能干啥  Authentication：认证 Authorization：授权 Session Management：会话管理；特定于用户的会话管理，及shiro自带的session Cr">
<meta property="og:type" content="article">
<meta property="og:title" content="springboot集成安全框架">
<meta property="og:url" content="http://hai-chao.gitee.io/blog/2022/02/12/27.springboot-ji-cheng-an-quan-kuang-jia/index.html">
<meta property="og:site_name" content="塔纳托斯">
<meta property="og:description" content="在java领域中有Spring Security和Apache Shiro等安全框架，本次记录中使用springboot来集成这两个框架 shiroshiro比spring security更轻量，功能更简单些 能干啥  Authentication：认证 Authorization：授权 Session Management：会话管理；特定于用户的会话管理，及shiro自带的session Cr">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://shiro.apache.org/images/ShiroFeatures.png">
<meta property="og:image" content="https://shiro.apache.org/images/ShiroBasicArchitecture.png">
<meta property="og:image" content="https://s6.jpg.cm/2022/02/12/L4AQ6e.png">
<meta property="og:image" content="https://s6.jpg.cm/2022/02/12/L4AdEy.png">
<meta property="og:image" content="https://s6.jpg.cm/2022/02/12/L4A5xk.png">
<meta property="og:image" content="https://s6.jpg.cm/2022/02/12/L4Anwi.png">
<meta property="og:image" content="https://s6.jpg.cm/2022/02/12/L4AWU8.png">
<meta property="og:image" content="https://s6.jpg.cm/2022/02/12/L4Aejr.png">
<meta property="og:image" content="https://s6.jpg.cm/2022/02/12/L4AUou.png">
<meta property="og:image" content="https://s6.jpg.cm/2022/02/12/L4AVtC.png">
<meta property="og:image" content="https://s6.jpg.cm/2022/02/12/L4A80t.png">
<meta property="og:image" content="https://s6.jpg.cm/2022/02/12/L4AXLR.png">
<meta property="og:image" content="https://s6.jpg.cm/2022/02/12/L4AcUz.png">
<meta property="article:published_time" content="2022-02-12T11:00:00.000Z">
<meta property="article:modified_time" content="2022-02-12T14:51:24.835Z">
<meta property="article:author" content="塔纳托斯">
<meta property="article:tag" content="学习">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://shiro.apache.org/images/ShiroFeatures.png">
    <link rel="stylesheet" href="/blog/lib/jquery.fancybox.min.css?v=1679297521065">
    
    <link rel="stylesheet" href="/blog/lib/mdui_043tiny/css/mdui.css?v=1679297521065">
    <link rel="stylesheet" href="/blog/lib/iconfont/iconfont.css?v=1679297521065">
    <link rel="stylesheet" href="/blog/css/style.css?v=1679297521065">
     
    
<meta name="generator" content="Hexo 5.3.0"><link rel="alternate" href="/blog/atom.xml" title="塔纳托斯" type="application/atom+xml">
<link rel="stylesheet" href="/blog/css/prism-tomorrow.css" type="text/css"></head>

<body class="mdui-drawer-body-left">
    
    <div id="nexmoe-background">
        <div class="nexmoe-bg" style="background-image: url(https://cdn.jsdelivr.net/gh/nexmoe/nexmoe.github.io@latest/images/cover/5c3aec85a4343.jpg)"></div>
        <div class="mdui-appbar mdui-shadow-0">
            <div class="mdui-toolbar">
                <a mdui-drawer="{target: '#drawer', swipe: true}" title="menu" class="mdui-btn mdui-btn-icon mdui-ripple"><i class="mdui-icon nexmoefont icon-menu"></i></a>
                <div class="mdui-toolbar-spacer"></div>
                <!--<a href="javascript:;" class="mdui-btn mdui-btn-icon"><i class="mdui-icon material-icons">search</i></a>-->
                <a href="/blog/" title="塔纳托斯" class="mdui-btn mdui-btn-icon"><img src="https://s6.jpg.cm/2022/01/17/LFpniO.md.jpg" alt="塔纳托斯"></a>
            </div>
        </div>
    </div>
    <div id="nexmoe-header">
        <div class="nexmoe-drawer mdui-drawer" id="drawer">
    <div class="nexmoe-avatar mdui-ripple">
        <a href="/blog/" title="塔纳托斯">
            <img src="https://s6.jpg.cm/2022/01/17/LFpniO.md.jpg" alt="塔纳托斯" alt="塔纳托斯">
        </a>
    </div>
    <div class="nexmoe-count">
        <div><span>文章</span>29</div>
        <div><span>标签</span>6</div>
        <div><span>分类</span>0</div>
    </div>
    <div class="nexmoe-list mdui-list" mdui-collapse="{accordion: true}">
        
        <a class="nexmoe-list-item mdui-list-item mdui-ripple false" href="/blog/" title="文章归档">
            <i class="mdui-list-item-icon nexmoefont icon-container"></i>
            <div class="mdui-list-item-content">
                文章归档
            </div>
        </a>
        
    </div>
    <aside id="nexmoe-sidebar">
    
    
  <div class="nexmoe-widget-wrap">
    <div id="randomtagcloud" class="nexmoe-widget tagcloud nexmoe-rainbow">
      <a href="/blog/tags/java/" style="font-size: 10px;">java</a> <a href="/blog/tags/%E5%88%86%E4%BA%AB/" style="font-size: 20px;">分享</a> <a href="/blog/tags/%E5%90%83%E7%93%9C/" style="font-size: 10px;">吃瓜</a> <a href="/blog/tags/%E5%AD%A6%E4%B9%A0/" style="font-size: 16.67px;">学习</a> <a href="/blog/tags/%E6%80%BB%E7%BB%93/" style="font-size: 13.33px;">总结</a> <a href="/blog/tags/%E6%B8%B8%E5%90%8E%E6%84%9F/" style="font-size: 10px;">游后感</a>
    </div>
    
  </div>

    
</aside>
    <div class="nexmoe-copyright">
        &copy; 2023 塔纳托斯
        Powered by <a href="http://hexo.io/" target="_blank">Hexo</a>
        & <a href="https://github.com/theme-nexmoe/hexo-theme-nexmoe" target="_blank">Nexmoe</a>
        
    </div>
</div><!-- .nexmoe-drawer -->
    </div>
    <div id="nexmoe-content">
        <div class="nexmoe-primary">
            <div class="nexmoe-post">

  <article>
      
          <div class="nexmoe-post-cover"> 
              
              <h1>springboot集成安全框架</h1>
          </div>
      
      
      <div class="nexmoe-post-meta nexmoe-rainbow" style="margin:10px 0!important;">
    <a><i class="nexmoefont icon-calendar-fill"></i>2022年02月12日</a>
</div>

      

      <p>在java领域中有Spring Security和Apache Shiro等安全框架，本次记录中使用springboot来集成这两个框架</p>
<h2 id="shiro"><a href="#shiro" class="headerlink" title="shiro"></a>shiro</h2><p>shiro比spring security更轻量，功能更简单些</p>
<h3 id="能干啥"><a href="#能干啥" class="headerlink" title="能干啥"></a>能干啥</h3><p><img src="https://shiro.apache.org/images/ShiroFeatures.png"></p>
<ul>
<li><strong>Authentication</strong>：认证</li>
<li><strong>Authorization</strong>：授权</li>
<li><strong>Session Management</strong>：会话管理；特定于用户的会话管理，及shiro自带的session</li>
<li><strong>Cryptography</strong>：加密；对数据源使用加密算法加密</li>
</ul>
<hr>
<p>其他功能起支持和加强作用</p>
<ul>
<li>Web支持：很轻松保护web应用安全</li>
<li>缓存：能使shiro的安全操作快速和高效</li>
<li>并发：shiro支持多线程应用程序的并发特性</li>
<li>测试：支持单元测试和集成测试</li>
<li>“Run As”：允许用户切换身份(在许可的前提下)</li>
<li>Remember me：记住我功能；能使用户的登录状态不会因为浏览器的关闭而失效，直到Cookie过期</li>
</ul>
<h3 id="核心"><a href="#核心" class="headerlink" title="核心"></a>核心</h3><p><img src="https://shiro.apache.org/images/ShiroBasicArchitecture.png"></p>
<p>shiro中三个主要核心组件：</p>
<p><code>Subject</code>：表示主体，代表当前进行安全操作的对象，可以是用户，也可以是一个运行的程序</p>
<p><code>SecurityManager</code>：安全管理器，对所有Subject进行安全管理</p>
<p><code>Realm</code>：充当了应用与数据安全间的<strong>桥梁</strong>或<strong>连接器</strong>，本质为一个特定的安全 DAO</p>
<h3 id="集成"><a href="#集成" class="headerlink" title="集成"></a>集成</h3><ul>
<li><strong><u>引入依赖</u></strong></li>
</ul>
<pre class=" language-xml"><code class="language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">></span></span>org.apache.shiro<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">></span></span>shiro-spring-boot-starter<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>version</span><span class="token punctuation">></span></span>1.4.2<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>version</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">></span></span></code></pre>
<ul>
<li><strong><u>自定义Realm类</u></strong></li>
</ul>
<pre class=" language-java"><code class="language-java"><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyRealm</span> <span class="token keyword">extends</span> <span class="token class-name">AuthorizingRealm</span> <span class="token punctuation">{</span>
    <span class="token comment" spellcheck="true">// 授权操作</span>
    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">protected</span> AuthorizationInfo <span class="token function">doGetAuthorizationInfo</span><span class="token punctuation">(</span>PrincipalCollection principalCollection<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> null<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token comment" spellcheck="true">// 认证操作</span>
    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">protected</span> AuthenticationInfo <span class="token function">doGetAuthenticationInfo</span><span class="token punctuation">(</span>AuthenticationToken authenticationToken<span class="token punctuation">)</span> <span class="token keyword">throws</span> AuthenticationException <span class="token punctuation">{</span>
        <span class="token keyword">return</span> null<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span></code></pre>
<ul>
<li><strong><u>配置shiro</u></strong></li>
</ul>
<pre class=" language-java"><code class="language-java"><span class="token annotation punctuation">@Configuration</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">ShiroConfig</span> <span class="token punctuation">{</span>
    <span class="token annotation punctuation">@Bean</span>
    <span class="token keyword">public</span> Realm <span class="token function">realm</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        MyRealm realm <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">MyRealm</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> realm<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token annotation punctuation">@Bean</span>
    <span class="token keyword">public</span> DefaultSecurityManager <span class="token function">securityManager</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        DefaultWebSecurityManager securityManager <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">DefaultWebSecurityManager</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        securityManager<span class="token punctuation">.</span><span class="token function">setRealm</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">realm</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> securityManager<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token annotation punctuation">@Bean</span>
    <span class="token keyword">public</span> ShiroFilterFactoryBean <span class="token function">shiroFilterFactoryBean</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        ShiroFilterFactoryBean bean <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ShiroFilterFactoryBean</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        bean<span class="token punctuation">.</span><span class="token function">setSecurityManager</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">securityManager</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

        <span class="token comment" spellcheck="true">// 设置过滤器</span>
        Map<span class="token operator">&lt;</span>String<span class="token punctuation">,</span> String<span class="token operator">></span> filterMap <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">LinkedHashMap</span><span class="token operator">&lt;</span><span class="token operator">></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token comment" spellcheck="true">// filterMap.put("/toAdd","authc");</span>
        bean<span class="token punctuation">.</span><span class="token function">setFilterChainDefinitionMap</span><span class="token punctuation">(</span>filterMap<span class="token punctuation">)</span><span class="token punctuation">;</span>

        <span class="token comment" spellcheck="true">// 设置URL</span>
        bean<span class="token punctuation">.</span><span class="token function">setLoginUrl</span><span class="token punctuation">(</span><span class="token string">"/toLogin"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        bean<span class="token punctuation">.</span><span class="token function">setUnauthorizedUrl</span><span class="token punctuation">(</span><span class="token string">"/"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

        <span class="token keyword">return</span> bean<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span></code></pre>
<p>在shiroFilterFactoryBean方法中可以设置<strong>过滤器</strong>，实现对请求的拦截</p>
<p><code>filterMap.put(&quot;/toAdd&quot;,&quot;authc&quot;);</code>——对<code>/toAdd</code>请求，用户需要认证才能通过请求</p>
<p>shiro中<strong>常用</strong>的内置过滤器：</p>
<ul>
<li><code>anon</code> ：AnonymousFilter ：允许匿名访问，即不需要登录</li>
<li><code>authc</code>：FormAuthenticationFilter ：需要经过认证的用户才可以访问</li>
<li><code>logout</code> ：LogoutFilter ：被拦截的URL执行退出操作，退出完成后，<strong>重定向</strong>到 <code>GET loginUrl</code> 登录页面</li>
<li><code>roles</code> ：RolesAuthorizationFilter ：拥有指定角色的用户才能访问。</li>
<li><code>perms</code> ：PermissionsAuthorizationFilter ：拥有指定权限的用户才能访问</li>
</ul>
<p>在shiro中提供了5个注解对应上述5个过滤操作，这5个注解可以直接添加在 SpringMVC 的 URL 对应的方法上，实现权限配置</p>
<ul>
<li><code>@RequiresGuest</code>——&gt;<code>anon</code></li>
<li><code>@RequiresAuthentication</code> ——&gt;<code>authc</code></li>
<li><code>@RequiresUser</code>——&gt;<code>user</code></li>
<li><code>@RequiresRoles</code>——&gt;<code>roles</code></li>
<li><code>@RequiresPermissions</code>——&gt;<code>perms</code></li>
</ul>
<p>对其中的<code>@RequiresRoles</code>和<code>@RequiresPermissions</code>演示：</p>
<pre class=" language-java"><code class="language-java"><span class="token comment" spellcheck="true">// 属于 NORMAL 角色</span>
<span class="token annotation punctuation">@RequiresRoles</span><span class="token punctuation">(</span><span class="token string">"NORMAL"</span><span class="token punctuation">)</span>
<span class="token comment" spellcheck="true">// 要同时拥有 ADMIN 和 NORMAL 角色</span>
<span class="token annotation punctuation">@RequiresRoles</span><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token string">"ADMIN"</span><span class="token punctuation">,</span> <span class="token string">"NORMAL"</span><span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token comment" spellcheck="true">// 拥有 ADMIN 或 NORMAL 任一角色即可</span>
<span class="token annotation punctuation">@RequiresRoles</span><span class="token punctuation">(</span>value <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token string">"ADMIN"</span><span class="token punctuation">,</span> <span class="token string">"NORMAL"</span><span class="token punctuation">}</span><span class="token punctuation">,</span> logical <span class="token operator">=</span> Logical<span class="token punctuation">.</span>OR<span class="token punctuation">)</span>

<span class="token comment" spellcheck="true">// 拥有 user:add 权限</span>
<span class="token annotation punctuation">@RequiresPermissions</span><span class="token punctuation">(</span><span class="token string">"user:add"</span><span class="token punctuation">)</span>
<span class="token comment" spellcheck="true">// 要同时拥有 user:add 和 user:update 权限</span>
<span class="token annotation punctuation">@RequiresPermissions</span><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token string">"user:add"</span><span class="token punctuation">,</span> <span class="token string">"user:update"</span><span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token comment" spellcheck="true">// 拥有 user:add 和 user:update 任一权限即可</span>
<span class="token annotation punctuation">@RequiresPermissions</span><span class="token punctuation">(</span>value <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token string">"user:add"</span><span class="token punctuation">,</span> <span class="token string">"user:update"</span><span class="token punctuation">}</span><span class="token punctuation">,</span> logical <span class="token operator">=</span> Logical<span class="token punctuation">.</span>OR<span class="token punctuation">)</span></code></pre>
<hr>
<p>在shiroFilterFactoryBean方法中可以设置<strong>URL</strong></p>
<ul>
<li><code>setLoginUrl(String loginUrl)</code> 方法，设置登录 URL 。在 Shiro 中，约定 <code>GET loginUrl</code> 为登录页面，<code>POST loginUrl</code> 为登录请求</li>
<li><code>setSuccessUrl(String successUrl)</code> 方法，设置登录成功 URL 。在登录成功时，会<strong>重定向</strong>到该 URL 上</li>
<li><code>setUnauthorizedUrl(String unauthorizedUrl)</code> 方法，设置无权限的 URL 。在请求校验权限不通过时，会<strong>重定向</strong>到该 URL 上</li>
</ul>
<hr>
<ul>
<li><strong><u>实现认证和授权方法</u></strong></li>
</ul>
<pre class=" language-java"><code class="language-java"><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyRealm</span> <span class="token keyword">extends</span> <span class="token class-name">AuthorizingRealm</span> <span class="token punctuation">{</span>
    <span class="token comment" spellcheck="true">// 授权操作</span>
    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">protected</span> AuthorizationInfo <span class="token function">doGetAuthorizationInfo</span><span class="token punctuation">(</span>PrincipalCollection principalCollection<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment" spellcheck="true">/*根据需要进行实现*/</span>
        <span class="token keyword">return</span> null<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token comment" spellcheck="true">// 认证操作</span>
    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">protected</span> AuthenticationInfo <span class="token function">doGetAuthenticationInfo</span><span class="token punctuation">(</span>AuthenticationToken authenticationToken<span class="token punctuation">)</span> <span class="token keyword">throws</span> AuthenticationException <span class="token punctuation">{</span>
        <span class="token comment" spellcheck="true">/*根据需要进行实现*/</span>
        <span class="token keyword">return</span> null<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span></code></pre>
<ul>
<li><strong><u>在controller中调用shiro的login方法</u></strong></li>
</ul>
<pre class=" language-java"><code class="language-java"><span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span><span class="token string">"/login"</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> String <span class="token function">login</span><span class="token punctuation">(</span>String username<span class="token punctuation">,</span>String password<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment" spellcheck="true">// 获取subject</span>
    Subject subject <span class="token operator">=</span> SecurityUtils<span class="token punctuation">.</span><span class="token function">getSubject</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    UsernamePasswordToken token <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">UsernamePasswordToken</span><span class="token punctuation">(</span>username<span class="token punctuation">,</span>password<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">try</span> <span class="token punctuation">{</span>
        <span class="token comment" spellcheck="true">// 调用login方法，对用户进行认证</span>
        subject<span class="token punctuation">.</span><span class="token function">login</span><span class="token punctuation">(</span>token<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> <span class="token string">"index"</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">UnknownAccountException</span> e<span class="token punctuation">)</span><span class="token punctuation">{</span>
        System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"账号不存在"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> <span class="token string">"login"</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">IncorrectCredentialsException</span> e<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"密码错误"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> <span class="token string">"login"</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span> <span class="token keyword">catch</span><span class="token punctuation">(</span>LockedAccountException e<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"帐号被锁定"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> <span class="token string">"login"</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span> <span class="token keyword">catch</span><span class="token punctuation">(</span>ExpiredCredentialsException e<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"帐号已过期"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> <span class="token string">"login"</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span></code></pre>
<h2 id="spring-security"><a href="#spring-security" class="headerlink" title="spring security"></a>spring security</h2><h3 id="能干啥-1"><a href="#能干啥-1" class="headerlink" title="能干啥"></a>能干啥</h3><ul>
<li>Comprehensive and extensible support for both Authentication and Authorization</li>
<li>Protection against attacks like session fixation, clickjacking, cross site request forgery, etc</li>
<li>Servlet API integration</li>
<li>Optional integration with Spring Web MVC</li>
<li>Much more…</li>
</ul>
<p>从官网介绍拷的，可以看出，能做认证、授权、防止会话固定、点击劫持、跨站点请求伪造等攻击，Servlet API的集成和可选择与springmvc集成等等</p>
<h3 id="集成-1"><a href="#集成-1" class="headerlink" title="集成"></a>集成</h3><ul>
<li><strong><u>引入依赖</u></strong></li>
</ul>
<pre class=" language-xml"><code class="language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">></span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">></span></span>spring-boot-starter-security<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">></span></span></code></pre>
<ul>
<li><strong><u>启动应用</u></strong></li>
</ul>
<p>简单写个TestController后启动应用访问路径，会看到</p>
<p><img src="https://s6.jpg.cm/2022/02/12/L4AQ6e.png"></p>
<p>这是因为没有做配置，所以会被Spring Security拦截所有的请求，并跳转到登录界面，这个登录界面是<code>DefaultLoginPageGeneratingFilter</code>类生成的</p>
<ul>
<li><strong><u>springboot配置文件</u></strong></li>
</ul>
<p>可以在<code>application.yml</code>中添加Spring Security配置，对<code>spring.security.user</code>进行配置将会使<code>UserDetailsServiceAutoConfiguration</code>类基于配置的信息在内存中创建一个用户<code>User</code>；不对<code>spring.security.user</code>配置时，<code>UserDetailsServiceAutoConfiguration</code>类会自动在内存中创建一个用户名为 <code>&quot;user&quot;</code> ，密码为 UUID 随机的用户<code>User</code></p>
<pre class=" language-yml"><code class="language-yml">spring:
  # Spring Security 配置项，对应 SecurityProperties 配置类
  security:
    # 配置默认的 InMemoryUserDetailsManager 的用户账号与密码。
    user:
      name: user # 账号
      password: user # 密码
      roles: ADMIN # 拥有角色</code></pre>
<ul>
<li><strong><u>SecurityConfig</u></strong></li>
</ul>
<pre class=" language-java"><code class="language-java"><span class="token annotation punctuation">@Configuration</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">SecurityConfig</span> <span class="token keyword">extends</span> <span class="token class-name">WebSecurityConfigurerAdapter</span> <span class="token punctuation">{</span>

    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">protected</span> <span class="token keyword">void</span> <span class="token function">configure</span><span class="token punctuation">(</span>AuthenticationManagerBuilder auth<span class="token punctuation">)</span> <span class="token keyword">throws</span> Exception <span class="token punctuation">{</span>
        <span class="token comment" spellcheck="true">// 在内存中添加用户，使用InMemoryUserDetailsManager</span>
        auth<span class="token punctuation">.</span><span class="token function">inMemoryAuthentication</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
            <span class="token comment" spellcheck="true">// PasswordEncoder:密码编码器</span>
            <span class="token comment" spellcheck="true">// BCryptPasswordEncoder:密码加密算法</span>
            <span class="token comment" spellcheck="true">// 增加了两个用户 user-password-role</span>
            <span class="token comment" spellcheck="true">// admin-admin-admin | normal-normal-normal</span>
            <span class="token punctuation">.</span><span class="token function">passwordEncoder</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">BCryptPasswordEncoder</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
            <span class="token punctuation">.</span><span class="token function">withUser</span><span class="token punctuation">(</span><span class="token string">"admin"</span><span class="token punctuation">)</span>
                <span class="token punctuation">.</span><span class="token function">password</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">BCryptPasswordEncoder</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">encode</span><span class="token punctuation">(</span><span class="token string">"admin"</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
                <span class="token punctuation">.</span><span class="token function">roles</span><span class="token punctuation">(</span><span class="token string">"admin"</span><span class="token punctuation">)</span>
            <span class="token punctuation">.</span><span class="token function">and</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">withUser</span><span class="token punctuation">(</span><span class="token string">"normal"</span><span class="token punctuation">)</span>
                <span class="token punctuation">.</span><span class="token function">password</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">BCryptPasswordEncoder</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">encode</span><span class="token punctuation">(</span><span class="token string">"normal"</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
                <span class="token punctuation">.</span><span class="token function">roles</span><span class="token punctuation">(</span><span class="token string">"normal"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">protected</span> <span class="token keyword">void</span> <span class="token function">configure</span><span class="token punctuation">(</span>HttpSecurity http<span class="token punctuation">)</span> <span class="token keyword">throws</span> Exception <span class="token punctuation">{</span>
        <span class="token comment" spellcheck="true">// 给URL授权</span>
        <span class="token comment" spellcheck="true">// /test/hello 所有用户可以访问</span>
        <span class="token comment" spellcheck="true">// /test/admin 需要admin角色</span>
        <span class="token comment" spellcheck="true">// /test/normal 需要normal角色</span>
        <span class="token comment" spellcheck="true">// 其他请求路径用户需要认证才能访问</span>
        http<span class="token punctuation">.</span><span class="token function">authorizeRequests</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
            <span class="token punctuation">.</span><span class="token function">antMatchers</span><span class="token punctuation">(</span><span class="token string">"/test/hello"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">permitAll</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
            <span class="token punctuation">.</span><span class="token function">antMatchers</span><span class="token punctuation">(</span><span class="token string">"/test/admin"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">hasRole</span><span class="token punctuation">(</span><span class="token string">"admin"</span><span class="token punctuation">)</span>
            <span class="token punctuation">.</span><span class="token function">antMatchers</span><span class="token punctuation">(</span><span class="token string">"/test/normal"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">hasRole</span><span class="token punctuation">(</span><span class="token string">"normal"</span><span class="token punctuation">)</span>
            <span class="token punctuation">.</span><span class="token function">anyRequest</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">authenticated</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
        <span class="token punctuation">.</span><span class="token function">and</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
        <span class="token comment" spellcheck="true">// 设置 Form 表单登录</span>
        <span class="token punctuation">.</span><span class="token function">formLogin</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
            <span class="token comment" spellcheck="true">// .loginPage("/login")  // 自定义登录路径</span>
        <span class="token punctuation">.</span><span class="token function">permitAll</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
        <span class="token punctuation">.</span><span class="token function">and</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
        <span class="token punctuation">.</span><span class="token function">logout</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
            <span class="token comment" spellcheck="true">// .logoutUrl("/logout") // 自定义登出路径</span>
        <span class="token punctuation">.</span><span class="token function">permitAll</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span></code></pre>
<p><code>SecurityConfig</code>继承<code>WebSecurityConfigurerAdapter</code>抽象类，重写方法<code>configure(AuthenticationManagerBuilder auth)</code>和<code>configure(HttpSecurity http) </code>，两方法的作用分别为：构建<code>AuthenticationManager</code>(认证管理器)；配置 URL的<strong>权限控制</strong></p>
<p>在方法<code>configure(AuthenticationManagerBuilder auth)</code>中，除了使用<code>inMemoryAuthentication</code>外，Spring还内置了<code>JdbcUserDetailsManager</code>；在实际项目使用中，一般自定义实现的<code>UserDetailsService</code>实现类</p>
<hr>
<p>在方法<code>configure(HttpSecurity http)</code>中，有些权限控制的方法：</p>
<table>
<thead>
<tr>
<th>方法</th>
<th>含义</th>
</tr>
</thead>
<tbody><tr>
<td>permitAll()</td>
<td>所有用户都能访问</td>
</tr>
<tr>
<td>denyAll()</td>
<td>所有用户都不能访问</td>
</tr>
<tr>
<td>authenticated()</td>
<td>登录用户可以访问</td>
</tr>
<tr>
<td>anonymous()</td>
<td>+不常用+；无需登录，即匿名用户可访问</td>
</tr>
<tr>
<td>rememberMe()</td>
<td>+不常用+；通过 remember me 登录的用户可访问</td>
</tr>
<tr>
<td>fullyAuthenticated()</td>
<td>+不常用+；非 remember me 登录的用户可访问</td>
</tr>
<tr>
<td>hasIpAddress(String ipaddressExpression)</td>
<td>+不常用+；指定 IP 表达式的用户可访问</td>
</tr>
<tr>
<td>hasRole(String role)</td>
<td>拥有指定角色的用户可访问</td>
</tr>
<tr>
<td>hasAnyRole(String… roles)</td>
<td>拥有指定任一角色的用户可访问</td>
</tr>
<tr>
<td>hasAuthority(String authority)</td>
<td>拥有指定权限(authority)的用户可访问</td>
</tr>
<tr>
<td>hasAuthority(String… authorities)</td>
<td>拥有指定任一权限(authority)的用户可访问</td>
</tr>
<tr>
<td>access(String attribute) 方法</td>
<td>当 Spring EL 表达式的执行结果为 true 时，可以访问</td>
</tr>
</tbody></table>
<p>与上述表格对应功能的是实现在controller上的注解，使用这些注解需要在<code>SecurityConfig</code>上加注解<code>@EnableGlobalMethodSecurity</code>，<code>@EnableGlobalMethodSecurity</code> 分别有<code>prePostEnabled</code> 、<code>securedEnabled</code>、<code>jsr250Enabled</code> 三个字段，其中每个字段代码是一种注解支持，默认为false，给值为true开启，看下面示例：</p>
<pre class=" language-java"><code class="language-java"><span class="token annotation punctuation">@Configuration</span>
<span class="token annotation punctuation">@EnableGlobalMethodSecurity</span><span class="token punctuation">(</span>prePostEnabled <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">)</span>  <span class="token comment" spellcheck="true">// 开启prePostEnabled注解</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">SecurityConfig</span> <span class="token keyword">extends</span> <span class="token class-name">WebSecurityConfigurerAdapter</span> <span class="token punctuation">{</span>    
<span class="token punctuation">}</span></code></pre>
<p>看下这些对应功能的注解：</p>
<ol>
<li>JSR-250注解<ul>
<li>@DenyAll——等同denyAll()，所有用户都不能访问</li>
<li>@RolesAllowed——等同hasAnyRole(String… roles)，拥有指定任一角色的用户可访问</li>
<li>@PermitAll——等同permitAll()，所有用户都能访问</li>
</ul>
</li>
<li>securedEnabled注解<ul>
<li>@Secured——需要用户具有对应的角色/权限才能访问，若用户没有对应角色/权限，将会拒绝访问将引发异常；同时不支持Spring EL表达式</li>
</ul>
</li>
<li>prePostEnabled注解，<strong>支持Spring EL表达式</strong><ul>
<li>@PreAuthorize——等同access(String attribute)方法，进入方法之前鉴权</li>
<li>@PostAuthorize——方法执行之后才鉴权</li>
<li>@PostFilter——在方法执行之后执行，而且这里可以调用方法的返回值，然后对返回值进行过滤或处理或修改并返回</li>
<li>@PreFilter——在方法执行之前执行，而且这里可以调用方法的参数，然后对参数值进行过滤或处理或修改</li>
</ul>
</li>
</ol>
<h3 id="角色继承"><a href="#角色继承" class="headerlink" title="角色继承"></a>角色继承</h3><p>当某角色想要拥有其他角色的权限时，比如vip用户应该拥有普通用户的权限，可以通过角色继承来实现</p>
<p>在<code>SecurityConfig</code>中加入</p>
<pre class=" language-java"><code class="language-java"><span class="token annotation punctuation">@Bean</span>
RoleHierarchy <span class="token function">roleHierarchy</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    RoleHierarchyImpl roleHierarchy <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">RoleHierarchyImpl</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    String hierarchy <span class="token operator">=</span> <span class="token string">"ROLE_dba > ROLE_admin \n ROLE_admin > ROLE_user"</span><span class="token punctuation">;</span>
    roleHierarchy<span class="token punctuation">.</span><span class="token function">setHierarchy</span><span class="token punctuation">(</span>hierarchy<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> roleHierarchy<span class="token punctuation">;</span>
<span class="token punctuation">}</span></code></pre>
<p>在上述代码中，ROLE_dba拥有ROLE_admin的权限，而ROLE_admin拥有ROLE_user的权限</p>
<p><strong>注意在Spring Boot2.0.8前，分隔符是用的空格</strong></p>
<pre class=" language-java"><code class="language-java"><span class="token annotation punctuation">@Bean</span>
RoleHierarchy <span class="token function">roleHierarchy</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    RoleHierarchyImpl roleHierarchy <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">RoleHierarchyImpl</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    String hierarchy <span class="token operator">=</span> <span class="token string">"ROLE_dba > ROLE_admin ROLE_admin > ROLE_user"</span><span class="token punctuation">;</span>
    roleHierarchy<span class="token punctuation">.</span><span class="token function">setHierarchy</span><span class="token punctuation">(</span>hierarchy<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> roleHierarchy<span class="token punctuation">;</span>
<span class="token punctuation">}</span></code></pre>
<h2 id="jwt"><a href="#jwt" class="headerlink" title="jwt"></a>jwt</h2><h3 id="jwt的介绍"><a href="#jwt的介绍" class="headerlink" title="jwt的介绍"></a>jwt的介绍</h3><p>jwt，Json Web Token，是一种JSON风格的轻量级的授权和身份认证规范，可实现<strong>无状态</strong>、分布式的Web应用授权，授权主要通过数字签名的方式，以json对象为载体，在不同的服务终端之间安全的传输信息</p>
<p>解释下无状态：服务端不会保存任何客户端请求者的信息，客户端的每次请求须具备自描述信息，通过这些信息识别客户端身份</p>
<p>无状态带来的好处：</p>
<ul>
<li>减轻服务器的存储压力</li>
<li>方便进行集群化部署</li>
<li>客户端请求不需要访问到同一台服务器</li>
</ul>
<p>Token：令牌，使用token认证的优势和不足如下：</p>
<p>优势：</p>
<ul>
<li>无状态</li>
<li>有效避免CSRF攻击</li>
<li>适合移动端应用</li>
<li>单点登录友好</li>
</ul>
<p>不足：</p>
<ul>
<li>注销问题</li>
<li>续签问题</li>
<li>密码修改问题</li>
</ul>
<p>jwt作为一种规范，并没有和某一种语言绑定在一起，常用的Java实现是GitHub上的开源项目<strong>jjwt</strong></p>
<h3 id="jwt的组成"><a href="#jwt的组成" class="headerlink" title="jwt的组成"></a>jwt的组成</h3><p>jwt由三部分组成：Header（头部）、Payload（负载）、Signature（签名）</p>
<ul>
<li><p>Header：头部，通常头部有两部分信息：</p>
<ul>
<li>声明类型，这里是JWT</li>
<li>加密算法，自定义(rs256/base64/hs256)</li>
</ul>
<p>将会对头部进行Base64Url编码（可解码），得到第一部分数据</p>
</li>
</ul>
<pre class=" language-java"><code class="language-java"><span class="token punctuation">{</span>
    <span class="token string">"typ"</span><span class="token operator">:</span> <span class="token string">"JWT"</span><span class="token punctuation">,</span>
    <span class="token string">"alg"</span><span class="token operator">:</span> <span class="token string">"HS256"</span>
<span class="token punctuation">}</span></code></pre>
<ul>
<li><p>Payload：载荷，就是有效数据，在官方文档中(RFC7519)，这里给了7个示例信息：</p>
<ul>
<li>iss (issuer)：表示签发人</li>
<li>exp (expiration time)：表示token过期时间</li>
<li>sub (subject)：主题</li>
<li>aud (audience)：受众</li>
<li>nbf (Not Before)：生效时间</li>
<li>iat (Issued At)：签发时间</li>
<li>jti (JWT ID)：编号</li>
</ul>
<p>这部分也会采用Base64Url编码，得到第二部分数据</p>
</li>
<li><p>Signature：签名，是整个数据的认证信息。这个部分需要base64加密后的header和base64加密后的payload使用<code>.</code>连接组成的字符串，然后通过header中声明的加密方式进行加盐<code>secret</code>组合加密，然后就构成了jwt的第三部分</p>
</li>
</ul>
<h3 id="练习"><a href="#练习" class="headerlink" title="练习"></a>练习</h3><p>简单写个单元测试来熟悉一下</p>
<ul>
<li><strong><u>引入依赖</u></strong></li>
</ul>
<pre class=" language-xml"><code class="language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">></span></span>io.jsonwebtoken<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">></span></span>jjwt<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>version</span><span class="token punctuation">></span></span>0.9.1<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>version</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">></span></span></code></pre>
<ul>
<li><strong><u>写测试</u></strong></li>
</ul>
<pre class=" language-java"><code class="language-java"><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">JwtTest</span> <span class="token punctuation">{</span>

    <span class="token keyword">private</span> <span class="token keyword">long</span> time <span class="token operator">=</span> <span class="token number">1000</span><span class="token operator">*</span><span class="token number">60</span><span class="token operator">*</span><span class="token number">60</span><span class="token operator">*</span><span class="token number">24</span><span class="token punctuation">;</span>
    <span class="token keyword">private</span> String secret <span class="token operator">=</span> <span class="token string">"www"</span><span class="token punctuation">;</span>

    <span class="token annotation punctuation">@Test</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">jwt</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        JwtBuilder builder <span class="token operator">=</span> Jwts<span class="token punctuation">.</span><span class="token function">builder</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        String jwtToken <span class="token operator">=</span> builder
                <span class="token comment" spellcheck="true">//header</span>
                <span class="token punctuation">.</span><span class="token function">setHeaderParam</span><span class="token punctuation">(</span><span class="token string">"typ"</span><span class="token punctuation">,</span><span class="token string">"JWT"</span><span class="token punctuation">)</span>
                <span class="token punctuation">.</span><span class="token function">setHeaderParam</span><span class="token punctuation">(</span><span class="token string">"alg"</span><span class="token punctuation">,</span><span class="token string">"HS256"</span><span class="token punctuation">)</span>
                <span class="token comment" spellcheck="true">//payload</span>
                <span class="token punctuation">.</span><span class="token function">claim</span><span class="token punctuation">(</span><span class="token string">"username"</span><span class="token punctuation">,</span><span class="token string">"tom"</span><span class="token punctuation">)</span>
                <span class="token punctuation">.</span><span class="token function">claim</span><span class="token punctuation">(</span><span class="token string">"role"</span><span class="token punctuation">,</span><span class="token string">"admin"</span><span class="token punctuation">)</span>
                <span class="token punctuation">.</span><span class="token function">setSubject</span><span class="token punctuation">(</span><span class="token string">"admin-test"</span><span class="token punctuation">)</span>   <span class="token comment" spellcheck="true">//设置主题为admin-test</span>
                <span class="token punctuation">.</span><span class="token function">setExpiration</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span>System<span class="token punctuation">.</span><span class="token function">currentTimeMillis</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> time<span class="token punctuation">)</span><span class="token punctuation">)</span>  <span class="token comment" spellcheck="true">//设置有效期为1天</span>
                <span class="token punctuation">.</span><span class="token function">setId</span><span class="token punctuation">(</span>UUID<span class="token punctuation">.</span><span class="token function">randomUUID</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
                <span class="token comment" spellcheck="true">//signature</span>
                <span class="token punctuation">.</span><span class="token function">signWith</span><span class="token punctuation">(</span>SignatureAlgorithm<span class="token punctuation">.</span>HS256<span class="token punctuation">,</span>secret<span class="token punctuation">)</span>   <span class="token comment" spellcheck="true">//加盐secret组合加密</span>
                <span class="token punctuation">.</span><span class="token function">compact</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>   <span class="token comment" spellcheck="true">//将三部分组合起来</span>

        System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>jwtToken<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

<span class="token punctuation">}</span></code></pre>
<p>运行看看</p>
<p><img src="https://s6.jpg.cm/2022/02/12/L4AdEy.png"></p>
<p>报错了，上网查找后发现是<strong>key不能太短 最短四个字符！！！</strong></p>
<p>把secret修改成4个字符以上，修改成”wwws”后再运行看看</p>
<p><img src="https://s6.jpg.cm/2022/02/12/L4A5xk.png"></p>
<p>成功得到token，可看出token的三部分，使用<code>.</code>分割的</p>
<pre class=" language-text"><code class="language-text">eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6InRvbSIsInJvbGUiOiJhZG1pbiIsInN1YiI6ImFkbWluLXRlc3QiLCJleHAiOjE2NDQ1ODk4NDEsImp0aSI6Ijk2MDFjZWQ2LThmYjYtNDU2OS04NzRhLTE3YTFiMjJhZjUwZiJ9.lJ1eE-btWEvlc2Xvbts0ilctBzM6YikSrJHygzBkc4g</code></pre>
<ul>
<li><strong><u>写方法解析上述得到token</u></strong></li>
</ul>
<pre class=" language-java"><code class="language-java">    <span class="token annotation punctuation">@Test</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">parse</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        String token <span class="token operator">=</span> <span class="token string">"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6InRvbSIsInJvbGUiOiJhZG1pbiIsInN1YiI6ImFkbWluLXRlc3QiLCJleHAiOjE2NDQ1ODk4NDEsImp0aSI6Ijk2MDFjZWQ2LThmYjYtNDU2OS04NzRhLTE3YTFiMjJhZjUwZiJ9.lJ1eE-btWEvlc2Xvbts0ilctBzM6YikSrJHygzBkc4g"</span><span class="token punctuation">;</span>
        JwtParser parser <span class="token operator">=</span> Jwts<span class="token punctuation">.</span><span class="token function">parser</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        Jws<span class="token operator">&lt;</span>Claims<span class="token operator">></span> claimsJws <span class="token operator">=</span> parser<span class="token punctuation">.</span><span class="token function">setSigningKey</span><span class="token punctuation">(</span>secret<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">parseClaimsJws</span><span class="token punctuation">(</span>token<span class="token punctuation">)</span><span class="token punctuation">;</span>
        Claims body <span class="token operator">=</span> claimsJws<span class="token punctuation">.</span><span class="token function">getBody</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

        System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>body<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string">"username"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>body<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string">"role"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>body<span class="token punctuation">.</span><span class="token function">getSubject</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>body<span class="token punctuation">.</span><span class="token function">getExpiration</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>body<span class="token punctuation">.</span><span class="token function">getId</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span></code></pre>
<p>运行看看结果，成功拿到token中的信息</p>
<p><img src="https://s6.jpg.cm/2022/02/12/L4Anwi.png"></p>
<h2 id="springsecurity-jwt"><a href="#springsecurity-jwt" class="headerlink" title="springsecurity + jwt"></a>springsecurity + jwt</h2><ul>
<li><strong><u>引入依赖</u></strong></li>
</ul>
<pre class=" language-xml"><code class="language-xml"><span class="token comment" spellcheck="true">&lt;!-- security --></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">></span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">></span></span>spring-boot-starter-security<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">></span></span>
<span class="token comment" spellcheck="true">&lt;!-- jwt --></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">></span></span>io.jsonwebtoken<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">></span></span>jjwt<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>version</span><span class="token punctuation">></span></span>0.9.1<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>version</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">></span></span></code></pre>
<ul>
<li><strong><u>JwtTokenUtils</u></strong></li>
</ul>
<p><strong>TOKEN_HEADER</strong>的值是客户端发送请求的header中需要带的属性，<strong>TOKEN_PREFIX</strong>是发送客户端发送的token值需要加的前缀</p>
<pre class=" language-java"><code class="language-java"><span class="token keyword">import</span> io<span class="token punctuation">.</span>jsonwebtoken<span class="token punctuation">.</span>*<span class="token punctuation">;</span>
<span class="token keyword">import</span> java<span class="token punctuation">.</span>util<span class="token punctuation">.</span>Date<span class="token punctuation">;</span>
<span class="token keyword">import</span> java<span class="token punctuation">.</span>util<span class="token punctuation">.</span>HashMap<span class="token punctuation">;</span>
<span class="token keyword">import</span> java<span class="token punctuation">.</span>util<span class="token punctuation">.</span>Map<span class="token punctuation">;</span>

<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">JwtTokenUtils</span> <span class="token punctuation">{</span>
    <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">final</span> String TOKEN_HEADER <span class="token operator">=</span> <span class="token string">"Authorization"</span><span class="token punctuation">;</span>
    <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">final</span> String TOKEN_PREFIX <span class="token operator">=</span> <span class="token string">"Bearer "</span><span class="token punctuation">;</span>

    <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">final</span> String SECRET <span class="token operator">=</span> <span class="token string">"jwtsecret"</span><span class="token punctuation">;</span>
    <span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token keyword">final</span> Long EXPIRATION <span class="token operator">=</span> <span class="token number">60</span> <span class="token operator">*</span> <span class="token number">60</span> <span class="token operator">*</span> 12L<span class="token punctuation">;</span> <span class="token comment" spellcheck="true">//过期时间12小时</span>
    <span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token keyword">final</span> String ROLE <span class="token operator">=</span> <span class="token string">"role"</span><span class="token punctuation">;</span>

    <span class="token comment" spellcheck="true">//创建token</span>
    <span class="token keyword">public</span> <span class="token keyword">static</span> String <span class="token function">createToken</span><span class="token punctuation">(</span>String username<span class="token punctuation">,</span> String role<span class="token punctuation">,</span> <span class="token keyword">boolean</span> isRememberMe<span class="token punctuation">)</span><span class="token punctuation">{</span>
        Map map <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">HashMap</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        map<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span>ROLE<span class="token punctuation">,</span> role<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> Jwts<span class="token punctuation">.</span><span class="token function">builder</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
                <span class="token punctuation">.</span><span class="token function">setClaims</span><span class="token punctuation">(</span>map<span class="token punctuation">)</span>
                <span class="token punctuation">.</span><span class="token function">setSubject</span><span class="token punctuation">(</span>username<span class="token punctuation">)</span>
                <span class="token punctuation">.</span><span class="token function">setIssuedAt</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
                <span class="token punctuation">.</span><span class="token function">setExpiration</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span>System<span class="token punctuation">.</span><span class="token function">currentTimeMillis</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> EXPIRATION <span class="token operator">*</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
                <span class="token punctuation">.</span><span class="token function">signWith</span><span class="token punctuation">(</span>SignatureAlgorithm<span class="token punctuation">.</span>HS512<span class="token punctuation">,</span> SECRET<span class="token punctuation">)</span>
                <span class="token punctuation">.</span><span class="token function">compact</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token comment" spellcheck="true">//从token中获取用户名(此处的token是指去掉前缀之后的)</span>
    <span class="token keyword">public</span> <span class="token keyword">static</span> String <span class="token function">getUserName</span><span class="token punctuation">(</span>String token<span class="token punctuation">)</span><span class="token punctuation">{</span>
        String username<span class="token punctuation">;</span>
        <span class="token keyword">try</span> <span class="token punctuation">{</span>
            username <span class="token operator">=</span> <span class="token function">getTokenBody</span><span class="token punctuation">(</span>token<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getSubject</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">Exception</span> e<span class="token punctuation">)</span><span class="token punctuation">{</span>
            username <span class="token operator">=</span> null<span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token keyword">return</span> username<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">public</span> <span class="token keyword">static</span> String <span class="token function">getUserRole</span><span class="token punctuation">(</span>String token<span class="token punctuation">)</span><span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token punctuation">(</span>String<span class="token punctuation">)</span> <span class="token function">getTokenBody</span><span class="token punctuation">(</span>token<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>ROLE<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">private</span> <span class="token keyword">static</span> Claims <span class="token function">getTokenBody</span><span class="token punctuation">(</span>String token<span class="token punctuation">)</span><span class="token punctuation">{</span>
        Claims claims <span class="token operator">=</span> null<span class="token punctuation">;</span>
        <span class="token keyword">try</span><span class="token punctuation">{</span>
            claims <span class="token operator">=</span> Jwts<span class="token punctuation">.</span><span class="token function">parser</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">setSigningKey</span><span class="token punctuation">(</span>SECRET<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">parseClaimsJws</span><span class="token punctuation">(</span>token<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getBody</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span> <span class="token keyword">catch</span><span class="token punctuation">(</span>ExpiredJwtException e<span class="token punctuation">)</span><span class="token punctuation">{</span>
            e<span class="token punctuation">.</span><span class="token function">printStackTrace</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span> <span class="token keyword">catch</span><span class="token punctuation">(</span>UnsupportedJwtException e<span class="token punctuation">)</span><span class="token punctuation">{</span>
            e<span class="token punctuation">.</span><span class="token function">printStackTrace</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span> <span class="token keyword">catch</span><span class="token punctuation">(</span>MalformedJwtException e<span class="token punctuation">)</span><span class="token punctuation">{</span>
            e<span class="token punctuation">.</span><span class="token function">printStackTrace</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span> <span class="token keyword">catch</span><span class="token punctuation">(</span>SignatureException e<span class="token punctuation">)</span><span class="token punctuation">{</span>
            e<span class="token punctuation">.</span><span class="token function">printStackTrace</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span> <span class="token keyword">catch</span><span class="token punctuation">(</span>IllegalArgumentException e<span class="token punctuation">)</span><span class="token punctuation">{</span>
            e<span class="token punctuation">.</span><span class="token function">printStackTrace</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token keyword">return</span> claims<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token comment" spellcheck="true">//是否已过期</span>
    <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">boolean</span> <span class="token function">isExpiration</span><span class="token punctuation">(</span>String token<span class="token punctuation">)</span><span class="token punctuation">{</span>
        <span class="token keyword">try</span><span class="token punctuation">{</span>
            <span class="token keyword">return</span> <span class="token function">getTokenBody</span><span class="token punctuation">(</span>token<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getExpiration</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">before</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span> <span class="token keyword">catch</span><span class="token punctuation">(</span>Exception e<span class="token punctuation">)</span><span class="token punctuation">{</span>
            System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>e<span class="token punctuation">.</span><span class="token function">getMessage</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span></code></pre>
<ul>
<li><strong><u>security</u></strong></li>
</ul>
<p>先创建<strong>AjaxAuthenticationEntryPoint</strong>和<strong>AjaxAccessDeniedHandler</strong></p>
<p><strong>AjaxAuthenticationEntryPoint</strong>是未认证的处理点，及一个用户没登录就去点击一些需要登录才能访问的资源，这时请求会被直接拦到这个处理点在这儿处理</p>
<p><strong>AjaxAccessDeniedHandler</strong>是权限不足的处理器</p>
<pre class=" language-java"><code class="language-java"><span class="token keyword">import</span> com<span class="token punctuation">.</span>fasterxml<span class="token punctuation">.</span>jackson<span class="token punctuation">.</span>databind<span class="token punctuation">.</span>ObjectMapper<span class="token punctuation">;</span>
<span class="token keyword">import</span> org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>security<span class="token punctuation">.</span>core<span class="token punctuation">.</span>AuthenticationException<span class="token punctuation">;</span>
<span class="token keyword">import</span> org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>security<span class="token punctuation">.</span>web<span class="token punctuation">.</span>AuthenticationEntryPoint<span class="token punctuation">;</span>
<span class="token keyword">import</span> org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>stereotype<span class="token punctuation">.</span>Component<span class="token punctuation">;</span>

<span class="token keyword">import</span> javax<span class="token punctuation">.</span>servlet<span class="token punctuation">.</span>ServletException<span class="token punctuation">;</span>
<span class="token keyword">import</span> javax<span class="token punctuation">.</span>servlet<span class="token punctuation">.</span>http<span class="token punctuation">.</span>HttpServletRequest<span class="token punctuation">;</span>
<span class="token keyword">import</span> javax<span class="token punctuation">.</span>servlet<span class="token punctuation">.</span>http<span class="token punctuation">.</span>HttpServletResponse<span class="token punctuation">;</span>
<span class="token keyword">import</span> java<span class="token punctuation">.</span>io<span class="token punctuation">.</span>IOException<span class="token punctuation">;</span>
<span class="token keyword">import</span> java<span class="token punctuation">.</span>util<span class="token punctuation">.</span>HashMap<span class="token punctuation">;</span>
<span class="token keyword">import</span> java<span class="token punctuation">.</span>util<span class="token punctuation">.</span>Map<span class="token punctuation">;</span>

<span class="token annotation punctuation">@Component</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">AjaxAuthenticationEntryPoint</span> <span class="token keyword">implements</span> <span class="token class-name">AuthenticationEntryPoint</span> <span class="token punctuation">{</span>
    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">commence</span><span class="token punctuation">(</span>HttpServletRequest httpServletRequest<span class="token punctuation">,</span> HttpServletResponse httpServletResponse<span class="token punctuation">,</span> AuthenticationException e<span class="token punctuation">)</span> <span class="token keyword">throws</span> IOException<span class="token punctuation">,</span> ServletException <span class="token punctuation">{</span>
        httpServletResponse<span class="token punctuation">.</span><span class="token function">setCharacterEncoding</span><span class="token punctuation">(</span><span class="token string">"UTF-8"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        httpServletResponse<span class="token punctuation">.</span><span class="token function">setContentType</span><span class="token punctuation">(</span><span class="token string">"application/json"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

        Map<span class="token operator">&lt;</span>String<span class="token punctuation">,</span> Object<span class="token operator">></span> map <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">HashMap</span><span class="token operator">&lt;</span><span class="token operator">></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        map<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">"code"</span><span class="token punctuation">,</span> <span class="token number">401</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        map<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">"message"</span><span class="token punctuation">,</span> <span class="token string">"尚未登录，请登录！"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        httpServletResponse<span class="token punctuation">.</span><span class="token function">getWriter</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">ObjectMapper</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">writeValueAsString</span><span class="token punctuation">(</span>map<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span></code></pre>
<pre class=" language-java"><code class="language-java"><span class="token keyword">import</span> com<span class="token punctuation">.</span>fasterxml<span class="token punctuation">.</span>jackson<span class="token punctuation">.</span>databind<span class="token punctuation">.</span>ObjectMapper<span class="token punctuation">;</span>
<span class="token keyword">import</span> org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>security<span class="token punctuation">.</span>access<span class="token punctuation">.</span>AccessDeniedException<span class="token punctuation">;</span>
<span class="token keyword">import</span> org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>security<span class="token punctuation">.</span>web<span class="token punctuation">.</span>access<span class="token punctuation">.</span>AccessDeniedHandler<span class="token punctuation">;</span>
<span class="token keyword">import</span> org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>stereotype<span class="token punctuation">.</span>Component<span class="token punctuation">;</span>

<span class="token keyword">import</span> javax<span class="token punctuation">.</span>servlet<span class="token punctuation">.</span>ServletException<span class="token punctuation">;</span>
<span class="token keyword">import</span> javax<span class="token punctuation">.</span>servlet<span class="token punctuation">.</span>http<span class="token punctuation">.</span>HttpServletRequest<span class="token punctuation">;</span>
<span class="token keyword">import</span> javax<span class="token punctuation">.</span>servlet<span class="token punctuation">.</span>http<span class="token punctuation">.</span>HttpServletResponse<span class="token punctuation">;</span>
<span class="token keyword">import</span> java<span class="token punctuation">.</span>io<span class="token punctuation">.</span>IOException<span class="token punctuation">;</span>
<span class="token keyword">import</span> java<span class="token punctuation">.</span>util<span class="token punctuation">.</span>HashMap<span class="token punctuation">;</span>
<span class="token keyword">import</span> java<span class="token punctuation">.</span>util<span class="token punctuation">.</span>Map<span class="token punctuation">;</span>

<span class="token annotation punctuation">@Component</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">AjaxAccessDeniedHandler</span> <span class="token keyword">implements</span> <span class="token class-name">AccessDeniedHandler</span> <span class="token punctuation">{</span>
    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">handle</span><span class="token punctuation">(</span>HttpServletRequest httpServletRequest<span class="token punctuation">,</span> HttpServletResponse httpServletResponse<span class="token punctuation">,</span> AccessDeniedException e<span class="token punctuation">)</span> <span class="token keyword">throws</span> IOException<span class="token punctuation">,</span> ServletException <span class="token punctuation">{</span>
        httpServletResponse<span class="token punctuation">.</span><span class="token function">setCharacterEncoding</span><span class="token punctuation">(</span><span class="token string">"UTF-8"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        httpServletResponse<span class="token punctuation">.</span><span class="token function">setContentType</span><span class="token punctuation">(</span><span class="token string">"application/json"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

        Map<span class="token operator">&lt;</span>String<span class="token punctuation">,</span> Object<span class="token operator">></span> map <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">HashMap</span><span class="token operator">&lt;</span><span class="token operator">></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        map<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">"code"</span><span class="token punctuation">,</span> <span class="token number">403</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        map<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">"message"</span><span class="token punctuation">,</span> <span class="token string">"权限不足，请联系管理员！"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        httpServletResponse<span class="token punctuation">.</span><span class="token function">getWriter</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">ObjectMapper</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">writeValueAsString</span><span class="token punctuation">(</span>map<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span></code></pre>
<p>再创建<strong>JwtAuthenticationTokenFilter</strong>，在这儿记录下我的理解，认证token的过滤器，当一个请求过来，先看请求的header中是否有<strong>TOKEN_HEADER</strong>属性，没有直接放行</p>
<p>有<strong>TOKEN_HEADER</strong>属性并且这个属性的值有<strong>TOKEN_PREFIX</strong>前缀就把前缀去掉，获得token，将token中存储的username拿出，进行登录验证，得到返回的<strong>userDetails</strong></p>
<p>在判断一下token是否过期，一般这里是封装一个验证方法，没过期就将信息放入到springsecurity的安全容器中，然后放行</p>
<pre class=" language-java"><code class="language-java"><span class="token keyword">import</span> com<span class="token punctuation">.</span>haichao<span class="token punctuation">.</span>utils<span class="token punctuation">.</span>JwtTokenUtils<span class="token punctuation">;</span>
<span class="token keyword">import</span> org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>beans<span class="token punctuation">.</span>factory<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span>Autowired<span class="token punctuation">;</span>
<span class="token keyword">import</span> org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>security<span class="token punctuation">.</span>authentication<span class="token punctuation">.</span>UsernamePasswordAuthenticationToken<span class="token punctuation">;</span>
<span class="token keyword">import</span> org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>security<span class="token punctuation">.</span>core<span class="token punctuation">.</span>context<span class="token punctuation">.</span>SecurityContextHolder<span class="token punctuation">;</span>
<span class="token keyword">import</span> org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>security<span class="token punctuation">.</span>core<span class="token punctuation">.</span>userdetails<span class="token punctuation">.</span>UserDetails<span class="token punctuation">;</span>
<span class="token keyword">import</span> org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>security<span class="token punctuation">.</span>core<span class="token punctuation">.</span>userdetails<span class="token punctuation">.</span>UserDetailsService<span class="token punctuation">;</span>
<span class="token keyword">import</span> org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>security<span class="token punctuation">.</span>web<span class="token punctuation">.</span>authentication<span class="token punctuation">.</span>WebAuthenticationDetailsSource<span class="token punctuation">;</span>
<span class="token keyword">import</span> org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>stereotype<span class="token punctuation">.</span>Component<span class="token punctuation">;</span>
<span class="token keyword">import</span> org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>web<span class="token punctuation">.</span>filter<span class="token punctuation">.</span>OncePerRequestFilter<span class="token punctuation">;</span>

<span class="token keyword">import</span> javax<span class="token punctuation">.</span>servlet<span class="token punctuation">.</span>FilterChain<span class="token punctuation">;</span>
<span class="token keyword">import</span> javax<span class="token punctuation">.</span>servlet<span class="token punctuation">.</span>ServletException<span class="token punctuation">;</span>
<span class="token keyword">import</span> javax<span class="token punctuation">.</span>servlet<span class="token punctuation">.</span>http<span class="token punctuation">.</span>HttpServletRequest<span class="token punctuation">;</span>
<span class="token keyword">import</span> javax<span class="token punctuation">.</span>servlet<span class="token punctuation">.</span>http<span class="token punctuation">.</span>HttpServletResponse<span class="token punctuation">;</span>
<span class="token keyword">import</span> java<span class="token punctuation">.</span>io<span class="token punctuation">.</span>IOException<span class="token punctuation">;</span>

<span class="token annotation punctuation">@Component</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">JwtAuthenticationTokenFilter</span> <span class="token keyword">extends</span> <span class="token class-name">OncePerRequestFilter</span> <span class="token punctuation">{</span>

    <span class="token annotation punctuation">@Autowired</span>
    <span class="token keyword">private</span> UserDetailsService userDetailsService<span class="token punctuation">;</span>

    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">protected</span> <span class="token keyword">void</span> <span class="token function">doFilterInternal</span><span class="token punctuation">(</span>HttpServletRequest request<span class="token punctuation">,</span> HttpServletResponse response<span class="token punctuation">,</span> FilterChain filterChain<span class="token punctuation">)</span> <span class="token keyword">throws</span> ServletException<span class="token punctuation">,</span> IOException <span class="token punctuation">{</span>
        String authHeader <span class="token operator">=</span> request<span class="token punctuation">.</span><span class="token function">getHeader</span><span class="token punctuation">(</span>JwtTokenUtils<span class="token punctuation">.</span>TOKEN_HEADER<span class="token punctuation">)</span><span class="token punctuation">;</span>

        <span class="token keyword">if</span> <span class="token punctuation">(</span>null <span class="token operator">!=</span> authHeader <span class="token operator">&amp;&amp;</span> authHeader<span class="token punctuation">.</span><span class="token function">startsWith</span><span class="token punctuation">(</span>JwtTokenUtils<span class="token punctuation">.</span>TOKEN_PREFIX<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            String authToken <span class="token operator">=</span> authHeader<span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span>JwtTokenUtils<span class="token punctuation">.</span>TOKEN_PREFIX<span class="token punctuation">,</span><span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token comment" spellcheck="true">// 或者写成</span>
            <span class="token comment" spellcheck="true">// String authToken = authHeader.substring(JwtTokenUtils.TOKEN_PREFIX.length());</span>
            String username <span class="token operator">=</span> JwtTokenUtils<span class="token punctuation">.</span><span class="token function">getUserName</span><span class="token punctuation">(</span>authToken<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span>null <span class="token operator">!=</span> username <span class="token operator">&amp;&amp;</span> null <span class="token operator">==</span> SecurityContextHolder<span class="token punctuation">.</span><span class="token function">getContext</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getAuthentication</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
                UserDetails userDetails <span class="token operator">=</span> userDetailsService<span class="token punctuation">.</span><span class="token function">loadUserByUsername</span><span class="token punctuation">(</span>username<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>JwtTokenUtils<span class="token punctuation">.</span><span class="token function">isExpiration</span><span class="token punctuation">(</span>authToken<span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span> null <span class="token operator">!=</span> userDetails<span class="token punctuation">)</span> <span class="token punctuation">{</span>
                    UsernamePasswordAuthenticationToken authentication <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">UsernamePasswordAuthenticationToken</span><span class="token punctuation">(</span>userDetails<span class="token punctuation">,</span> null<span class="token punctuation">,</span> userDetails<span class="token punctuation">.</span><span class="token function">getAuthorities</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                    authentication<span class="token punctuation">.</span><span class="token function">setDetails</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">WebAuthenticationDetailsSource</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">buildDetails</span><span class="token punctuation">(</span>request<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                    SecurityContextHolder<span class="token punctuation">.</span><span class="token function">getContext</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">setAuthentication</span><span class="token punctuation">(</span>authentication<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
            <span class="token punctuation">}</span>
        <span class="token punctuation">}</span>
        filterChain<span class="token punctuation">.</span><span class="token function">doFilter</span><span class="token punctuation">(</span>request<span class="token punctuation">,</span>response<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span></code></pre>
<p>配置<strong>SecurityConfig</strong></p>
<p><strong>@EnableWebSecurity</strong>是开启SpringSecurity的默认行为，它的上面有一个Import注解导入了WebSecurityConfiguration类，也就是说加上了@EnableWebSecurity这个注解，就是往IOC容器中注入了WebSecurityConfiguration这个类</p>
<pre class=" language-java"><code class="language-java"><span class="token annotation punctuation">@EnableGlobalMethodSecurity</span><span class="token punctuation">(</span>prePostEnabled <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">)</span>
<span class="token annotation punctuation">@EnableWebSecurity</span>
<span class="token annotation punctuation">@Configuration</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">SecurityConfig</span> <span class="token keyword">extends</span> <span class="token class-name">WebSecurityConfigurerAdapter</span> <span class="token punctuation">{</span>

    <span class="token annotation punctuation">@Autowired</span>
    <span class="token keyword">private</span> AjaxAuthenticationEntryPoint ajaxAuthenticationEntryPoint<span class="token punctuation">;</span>
    <span class="token annotation punctuation">@Autowired</span>
    <span class="token keyword">private</span> AjaxAccessDeniedHandler ajaxAccessDeniedHandler<span class="token punctuation">;</span>
    <span class="token annotation punctuation">@Autowired</span>
    <span class="token keyword">private</span> UserMapper userMapper<span class="token punctuation">;</span>
    <span class="token annotation punctuation">@Autowired</span>
    <span class="token keyword">private</span> RoleMapper roleMapper<span class="token punctuation">;</span>
    <span class="token annotation punctuation">@Autowired</span>
    <span class="token keyword">private</span> JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter<span class="token punctuation">;</span>


    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">protected</span> <span class="token keyword">void</span> <span class="token function">configure</span><span class="token punctuation">(</span>AuthenticationManagerBuilder auth<span class="token punctuation">)</span> <span class="token keyword">throws</span> Exception <span class="token punctuation">{</span>
        <span class="token comment" spellcheck="true">// 加入自定义的安全认证</span>
        auth<span class="token punctuation">.</span><span class="token function">userDetailsService</span><span class="token punctuation">(</span><span class="token function">userDetailsService</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">passwordEncoder</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">BCryptPasswordEncoder</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">protected</span> <span class="token keyword">void</span> <span class="token function">configure</span><span class="token punctuation">(</span>HttpSecurity http<span class="token punctuation">)</span> <span class="token keyword">throws</span> Exception <span class="token punctuation">{</span>
        http<span class="token punctuation">.</span><span class="token function">csrf</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">disable</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
                <span class="token comment" spellcheck="true">//基于token，不需要session</span>
                <span class="token punctuation">.</span><span class="token function">sessionManagement</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">sessionCreationPolicy</span><span class="token punctuation">(</span>SessionCreationPolicy<span class="token punctuation">.</span>STATELESS<span class="token punctuation">)</span>
                <span class="token punctuation">.</span><span class="token function">and</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
                <span class="token comment" spellcheck="true">//所有请求都要求认证</span>
                <span class="token punctuation">.</span><span class="token function">authorizeRequests</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">anyRequest</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">authenticated</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
                <span class="token comment" spellcheck="true">//动态权限配置</span>
                <span class="token punctuation">.</span><span class="token function">and</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
                <span class="token comment" spellcheck="true">//禁用缓存</span>
                <span class="token punctuation">.</span><span class="token function">headers</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">cacheControl</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token comment" spellcheck="true">//添加jwt 登录授权过滤器</span>
        http<span class="token punctuation">.</span><span class="token function">addFilterBefore</span><span class="token punctuation">(</span>jwtAuthenticationTokenFilter<span class="token punctuation">,</span> UsernamePasswordAuthenticationFilter<span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token comment" spellcheck="true">//添加自定义未授权和未登录结果返回</span>
        http<span class="token punctuation">.</span><span class="token function">exceptionHandling</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
                <span class="token punctuation">.</span><span class="token function">accessDeniedHandler</span><span class="token punctuation">(</span>ajaxAccessDeniedHandler<span class="token punctuation">)</span>
                <span class="token punctuation">.</span><span class="token function">authenticationEntryPoint</span><span class="token punctuation">(</span>ajaxAuthenticationEntryPoint<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token comment" spellcheck="true">// 不拦截的路径</span>
    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">configure</span><span class="token punctuation">(</span>WebSecurity web<span class="token punctuation">)</span> <span class="token keyword">throws</span> Exception <span class="token punctuation">{</span>
        web<span class="token punctuation">.</span><span class="token function">ignoring</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">antMatchers</span><span class="token punctuation">(</span>
                <span class="token string">"/register"</span><span class="token punctuation">,</span>
                <span class="token string">"/login"</span><span class="token punctuation">,</span>
                <span class="token string">"/logout"</span><span class="token punctuation">,</span>
                <span class="token string">"/css/**"</span><span class="token punctuation">,</span>
                <span class="token string">"/js/**"</span><span class="token punctuation">,</span>
                <span class="token string">"/"</span><span class="token punctuation">,</span>
                <span class="token string">"/index.html"</span><span class="token punctuation">,</span>
                <span class="token string">"/login.html"</span><span class="token punctuation">,</span>
                <span class="token string">"/register.html"</span><span class="token punctuation">,</span>
                <span class="token string">"favicon.ico"</span><span class="token punctuation">,</span>
                <span class="token string">"/doc.html"</span><span class="token punctuation">,</span>
                <span class="token string">"/webjars/**"</span><span class="token punctuation">,</span>
                <span class="token string">"/swagger-resources/**"</span><span class="token punctuation">,</span>
                <span class="token string">"/v2/api-docs/**"</span><span class="token punctuation">,</span>
                <span class="token string">"/captcha"</span><span class="token punctuation">,</span>
                <span class="token string">"/ws/**"</span><span class="token punctuation">,</span>

                <span class="token string">"/test/**"</span>
        <span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token comment" spellcheck="true">// 实现userDetailsService接口的方法loadUserByUsername</span>
    <span class="token annotation punctuation">@Override</span>
    <span class="token annotation punctuation">@Bean</span>
    <span class="token keyword">public</span> UserDetailsService <span class="token function">userDetailsService</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
        <span class="token keyword">return</span> username <span class="token operator">-</span><span class="token operator">></span> <span class="token punctuation">{</span>
            User user <span class="token operator">=</span> userMapper<span class="token punctuation">.</span><span class="token function">findUserByUsername</span><span class="token punctuation">(</span>username<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span>null <span class="token operator">!=</span> user<span class="token punctuation">)</span><span class="token punctuation">{</span>

                List<span class="token operator">&lt;</span>Role<span class="token operator">></span> roles <span class="token operator">=</span> roleMapper<span class="token punctuation">.</span><span class="token function">findRoleByUserId</span><span class="token punctuation">(</span>user<span class="token punctuation">.</span><span class="token function">getId</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                Collection set <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">HashSet</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">for</span> <span class="token punctuation">(</span>Role role<span class="token operator">:</span>roles<span class="token punctuation">)</span> <span class="token punctuation">{</span>
                    set<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">SimpleGrantedAuthority</span><span class="token punctuation">(</span>role<span class="token punctuation">.</span><span class="token function">getRolename</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                user<span class="token punctuation">.</span><span class="token function">setAuthorities</span><span class="token punctuation">(</span>set<span class="token punctuation">)</span><span class="token punctuation">;</span>

                <span class="token keyword">return</span> user<span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">UsernameNotFoundException</span><span class="token punctuation">(</span><span class="token string">"用户名或密码不正确"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span></code></pre>
<ul>
<li><strong><u>建表</u></strong></li>
</ul>
<p><img src="https://s6.jpg.cm/2022/02/12/L4AWU8.png"></p>
<p><img src="https://s6.jpg.cm/2022/02/12/L4Aejr.png"></p>
<p><img src="https://s6.jpg.cm/2022/02/12/L4AUou.png"></p>
<ul>
<li><strong><u>根据表创建po对象</u></strong></li>
</ul>
<pre class=" language-java"><code class="language-java"><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">Role</span> <span class="token punctuation">{</span>
    <span class="token keyword">private</span> <span class="token keyword">int</span> id<span class="token punctuation">;</span>
    <span class="token keyword">private</span> String rolename<span class="token punctuation">;</span>

    <span class="token keyword">public</span> <span class="token keyword">int</span> <span class="token function">getId</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> id<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setId</span><span class="token punctuation">(</span><span class="token keyword">int</span> id<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>id <span class="token operator">=</span> id<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">public</span> String <span class="token function">getRolename</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> rolename<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setRolename</span><span class="token punctuation">(</span>String rolename<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>rolename <span class="token operator">=</span> rolename<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span></code></pre>
<pre class=" language-java"><code class="language-java"><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">User</span> <span class="token keyword">implements</span> <span class="token class-name">UserDetails</span> <span class="token punctuation">{</span>
    <span class="token keyword">private</span> Integer id<span class="token punctuation">;</span>
    <span class="token keyword">private</span> String username<span class="token punctuation">;</span>
    <span class="token keyword">private</span> String password<span class="token punctuation">;</span>
    <span class="token keyword">private</span> Collection<span class="token operator">&lt;</span><span class="token operator">?</span> <span class="token keyword">extends</span> <span class="token class-name">GrantedAuthority</span><span class="token operator">></span> authorities<span class="token punctuation">;</span>

    <span class="token keyword">public</span> Integer <span class="token function">getId</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> id<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setId</span><span class="token punctuation">(</span>Integer id<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>id <span class="token operator">=</span> id<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">public</span> String <span class="token function">getUsername</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> username<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setUsername</span><span class="token punctuation">(</span>String username<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>username <span class="token operator">=</span> username<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">public</span> String <span class="token function">getPassword</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> password<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setPassword</span><span class="token punctuation">(</span>String password<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>password <span class="token operator">=</span> password<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">public</span> Collection<span class="token operator">&lt;</span><span class="token operator">?</span> <span class="token keyword">extends</span> <span class="token class-name">GrantedAuthority</span><span class="token operator">></span> <span class="token function">getAuthorities</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> authorities<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setAuthorities</span><span class="token punctuation">(</span>Collection<span class="token operator">&lt;</span><span class="token operator">?</span> <span class="token keyword">extends</span> <span class="token class-name">GrantedAuthority</span><span class="token operator">></span> authorities<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>authorities <span class="token operator">=</span> authorities<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">public</span> <span class="token keyword">boolean</span> <span class="token function">isAccountNonExpired</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">public</span> <span class="token keyword">boolean</span> <span class="token function">isAccountNonLocked</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">public</span> <span class="token keyword">boolean</span> <span class="token function">isCredentialsNonExpired</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">public</span> <span class="token keyword">boolean</span> <span class="token function">isEnabled</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span></code></pre>
<ul>
<li><strong><u>mapper</u></strong></li>
</ul>
<pre class=" language-java"><code class="language-java"><span class="token annotation punctuation">@Mapper</span>
<span class="token keyword">public</span> <span class="token keyword">interface</span> <span class="token class-name">UserMapper</span> <span class="token punctuation">{</span>
    <span class="token annotation punctuation">@Select</span><span class="token punctuation">(</span><span class="token string">"select * from user where username = #{username}"</span><span class="token punctuation">)</span>
    User <span class="token function">findUserByUsername</span><span class="token punctuation">(</span>String username<span class="token punctuation">)</span> <span class="token punctuation">;</span>
    <span class="token annotation punctuation">@Insert</span><span class="token punctuation">(</span><span class="token string">"insert into user(username,password) values(#{user.username},#{user.password})"</span><span class="token punctuation">)</span>
    <span class="token keyword">boolean</span> <span class="token function">addUser</span><span class="token punctuation">(</span><span class="token annotation punctuation">@Param</span><span class="token punctuation">(</span><span class="token string">"user"</span><span class="token punctuation">)</span> User user<span class="token punctuation">)</span> <span class="token punctuation">;</span>
<span class="token punctuation">}</span></code></pre>
<pre class=" language-java"><code class="language-java"><span class="token annotation punctuation">@Mapper</span>
<span class="token keyword">public</span> <span class="token keyword">interface</span> <span class="token class-name">RoleMapper</span> <span class="token punctuation">{</span>
    <span class="token annotation punctuation">@Select</span><span class="token punctuation">(</span><span class="token string">"select r.* from role r left join user_role ur on r.id=ur.rid"</span> <span class="token operator">+</span>
            <span class="token string">" where ur.uid = #{uid}"</span><span class="token punctuation">)</span>
    List<span class="token operator">&lt;</span>Role<span class="token operator">></span> <span class="token function">findRoleByUserId</span><span class="token punctuation">(</span><span class="token keyword">int</span> uid<span class="token punctuation">)</span> <span class="token punctuation">;</span>

<span class="token punctuation">}</span></code></pre>
<ul>
<li><strong><u>LoginService</u></strong></li>
</ul>
<pre class=" language-java"><code class="language-java"><span class="token annotation punctuation">@Service</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">LoginService</span> <span class="token punctuation">{</span>
    <span class="token annotation punctuation">@Autowired</span>
    <span class="token keyword">private</span> UserDetailsService userDetailsService<span class="token punctuation">;</span>
    <span class="token annotation punctuation">@Autowired</span>
    <span class="token keyword">private</span> UserMapper userMapper<span class="token punctuation">;</span>
    <span class="token annotation punctuation">@Autowired</span>
    <span class="token keyword">private</span> RoleMapper roleMapper<span class="token punctuation">;</span>

    <span class="token keyword">public</span> String <span class="token function">login</span><span class="token punctuation">(</span>String username<span class="token punctuation">,</span>String password<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        UsernamePasswordAuthenticationToken upToken <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">UsernamePasswordAuthenticationToken</span><span class="token punctuation">(</span>username<span class="token punctuation">,</span> password<span class="token punctuation">)</span><span class="token punctuation">;</span>
        UserDetails userDetails <span class="token operator">=</span> userDetailsService<span class="token punctuation">.</span><span class="token function">loadUserByUsername</span><span class="token punctuation">(</span>username<span class="token punctuation">)</span><span class="token punctuation">;</span>
        String token <span class="token operator">=</span> JwtTokenUtils<span class="token punctuation">.</span><span class="token function">createToken</span><span class="token punctuation">(</span>userDetails<span class="token punctuation">.</span><span class="token function">getUsername</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> null<span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> token<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">public</span> Boolean <span class="token function">register</span><span class="token punctuation">(</span>User user<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">final</span> String username <span class="token operator">=</span> user<span class="token punctuation">.</span><span class="token function">getUsername</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>userMapper<span class="token punctuation">.</span><span class="token function">findUserByUsername</span><span class="token punctuation">(</span>username<span class="token punctuation">)</span> <span class="token operator">!=</span> null<span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token keyword">return</span> null<span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        BCryptPasswordEncoder encoder <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">BCryptPasswordEncoder</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">final</span> String password <span class="token operator">=</span> user<span class="token punctuation">.</span><span class="token function">getPassword</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        user<span class="token punctuation">.</span><span class="token function">setPassword</span><span class="token punctuation">(</span>encoder<span class="token punctuation">.</span><span class="token function">encode</span><span class="token punctuation">(</span>password<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> userMapper<span class="token punctuation">.</span><span class="token function">addUser</span><span class="token punctuation">(</span>user<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span></code></pre>
<ul>
<li><strong><u>controller</u></strong></li>
</ul>
<pre class=" language-java"><code class="language-java"><span class="token annotation punctuation">@RestController</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">LoginController</span> <span class="token punctuation">{</span>
    <span class="token annotation punctuation">@Autowired</span>
    <span class="token keyword">private</span> LoginService loginService<span class="token punctuation">;</span>

    <span class="token annotation punctuation">@PostMapping</span><span class="token punctuation">(</span><span class="token string">"/login"</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> String <span class="token function">login</span><span class="token punctuation">(</span><span class="token annotation punctuation">@RequestBody</span> User user<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        String login <span class="token operator">=</span> loginService<span class="token punctuation">.</span><span class="token function">login</span><span class="token punctuation">(</span>user<span class="token punctuation">.</span><span class="token function">getUsername</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> user<span class="token punctuation">.</span><span class="token function">getPassword</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> login<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token annotation punctuation">@PostMapping</span><span class="token punctuation">(</span><span class="token string">"/register"</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> String <span class="token function">register</span><span class="token punctuation">(</span><span class="token annotation punctuation">@RequestBody</span> User user<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        Boolean register <span class="token operator">=</span> loginService<span class="token punctuation">.</span><span class="token function">register</span><span class="token punctuation">(</span>user<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>register<span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token keyword">return</span> <span class="token string">"注册失败!"</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token keyword">return</span> <span class="token string">"注册成功!"</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span></code></pre>
<pre class=" language-java"><code class="language-java"><span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span><span class="token string">"/test"</span><span class="token punctuation">)</span>
<span class="token annotation punctuation">@RestController</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">TestController</span> <span class="token punctuation">{</span>

    <span class="token annotation punctuation">@PreAuthorize</span><span class="token punctuation">(</span><span class="token string">"hasAnyAuthority('admin')"</span><span class="token punctuation">)</span>
    <span class="token annotation punctuation">@PostMapping</span><span class="token punctuation">(</span><span class="token string">"/admin"</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> String <span class="token function">admin</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token string">"我是管理员"</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token annotation punctuation">@GetMapping</span><span class="token punctuation">(</span><span class="token string">"/normal"</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> String <span class="token function">normal</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token string">"我是普通用户"</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span></code></pre>
<ul>
<li><strong><u>静态资源</u></strong></li>
</ul>
<p>封装请求，目前不会vue，就简单用js封装一下，及请求路径不是<code>/login</code>时都会带上token，<strong>func</strong>是请求得到结果之后要执行的方法</p>
<pre class=" language-js"><code class="language-js"><span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">sendHttp</span><span class="token punctuation">(</span>path<span class="token punctuation">,</span>method<span class="token punctuation">,</span>data<span class="token punctuation">,</span>func<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">let</span> url <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">URL</span><span class="token punctuation">(</span>path<span class="token punctuation">,</span>location<span class="token punctuation">.</span>origin<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">let</span> init <span class="token operator">=</span> <span class="token punctuation">{</span>
        method <span class="token punctuation">:</span> method<span class="token punctuation">,</span>
        headers<span class="token punctuation">:</span> <span class="token punctuation">{</span>
            <span class="token string">"Content-type"</span> <span class="token punctuation">:</span> <span class="token string">"application/json;charset=utf-8"</span>
        <span class="token punctuation">}</span><span class="token punctuation">,</span>
        body<span class="token punctuation">:</span> data<span class="token operator">===</span><span class="token keyword">null</span><span class="token operator">?</span> <span class="token keyword">null</span><span class="token punctuation">:</span>JSON<span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span>
    <span class="token punctuation">}</span><span class="token punctuation">;</span>

    <span class="token keyword">if</span> <span class="token punctuation">(</span>path <span class="token operator">!=</span> <span class="token string">"/login"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        init<span class="token punctuation">.</span>headers<span class="token punctuation">.</span>Authorization <span class="token operator">=</span> sessionStorage<span class="token punctuation">.</span><span class="token function">getItem</span><span class="token punctuation">(</span><span class="token string">"token"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">let</span> response <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">fetch</span><span class="token punctuation">(</span>url<span class="token punctuation">,</span>init<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">let</span> result <span class="token operator">=</span> <span class="token keyword">await</span> response<span class="token punctuation">.</span><span class="token function">text</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">func</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span></code></pre>
<p>index.html</p>
<p>这里跳转路径被难到了，超链接要跳转的资源是未被放行的，是需要认证后才能访问，但点击超链接发出的请求不知怎么改header，所有先用**write()**方法来覆盖当前页面</p>
<pre class=" language-html"><code class="language-html"><span class="token doctype">&lt;!DOCTYPE html></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>html</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>en<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>head</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>meta</span> <span class="token attr-name">charset</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>UTF-8<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>title</span><span class="token punctuation">></span></span>Index<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>title</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>head</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>body</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h1</span><span class="token punctuation">></span></span>主页<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h1</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>br</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>register.html<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>注册<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>br</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>login.html<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>登录<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>br</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>a-test<span class="token punctuation">"</span></span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>#<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>page1<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>br</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>hr</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>btn1<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>toAdmin<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>body</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span><span class="token punctuation">></span></span><span class="token script language-javascript">
    document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">"#a-test"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"click"</span><span class="token punctuation">,</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">let</span> result <span class="token operator">=</span> <span class="token function">sendHttp</span><span class="token punctuation">(</span><span class="token string">"/page1.html"</span><span class="token punctuation">,</span><span class="token string">"GET"</span><span class="token punctuation">,</span><span class="token keyword">null</span><span class="token punctuation">,</span><span class="token keyword">function</span> <span class="token punctuation">(</span>result<span class="token punctuation">)</span> <span class="token punctuation">{</span>
            document<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">"#btn1"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"click"</span><span class="token punctuation">,</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">let</span> result <span class="token operator">=</span> <span class="token function">sendHttp</span><span class="token punctuation">(</span><span class="token string">"/test/admin"</span><span class="token punctuation">,</span><span class="token string">"POST"</span><span class="token punctuation">,</span><span class="token keyword">null</span><span class="token punctuation">,</span><span class="token keyword">function</span> <span class="token punctuation">(</span>result<span class="token punctuation">)</span> <span class="token punctuation">{</span>
            console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>js/sentHttp.js<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token script language-javascript"></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>html</span><span class="token punctuation">></span></span></code></pre>
<p>login.html</p>
<pre class=" language-html"><code class="language-html"><span class="token doctype">&lt;!DOCTYPE html></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>html</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>en<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>head</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>meta</span> <span class="token attr-name">charset</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>UTF-8<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>title</span><span class="token punctuation">></span></span>Login<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>title</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>head</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>body</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h1</span><span class="token punctuation">></span></span>Login<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h1</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>form</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>formItem<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
    用户名:<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>username<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>br</span><span class="token punctuation">></span></span>
    密码:<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>password<span class="token punctuation">"</span></span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>password<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>br</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>form</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>btn<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>提交<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>body</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span><span class="token punctuation">></span></span><span class="token script language-javascript">
    document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">"#btn"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"click"</span><span class="token punctuation">,</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">let</span> formItem <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">"#formItem"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
        <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> el <span class="token keyword">of</span> formItem<span class="token punctuation">.</span>children<span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span>el<span class="token punctuation">.</span><span class="token function">hasAttribute</span><span class="token punctuation">(</span><span class="token string">"name"</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
                user<span class="token punctuation">[</span>el<span class="token punctuation">.</span><span class="token function">getAttribute</span><span class="token punctuation">(</span><span class="token string">"name"</span><span class="token punctuation">)</span><span class="token punctuation">]</span> <span class="token operator">=</span> el<span class="token punctuation">.</span>value<span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
        <span class="token punctuation">}</span>

        <span class="token function">sendHttp</span><span class="token punctuation">(</span><span class="token string">"/login"</span><span class="token punctuation">,</span><span class="token string">"POST"</span><span class="token punctuation">,</span>user<span class="token punctuation">,</span><span class="token keyword">function</span> <span class="token punctuation">(</span>result<span class="token punctuation">)</span> <span class="token punctuation">{</span>
            console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">;</span>
            sessionStorage<span class="token punctuation">.</span><span class="token function">setItem</span><span class="token punctuation">(</span><span class="token string">"token"</span><span class="token punctuation">,</span><span class="token string">"Bearer "</span> <span class="token operator">+</span> result<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>js/sentHttp.js<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token script language-javascript"></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>html</span><span class="token punctuation">></span></span></code></pre>
<p>register.html</p>
<pre class=" language-html"><code class="language-html"><span class="token doctype">&lt;!DOCTYPE html></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>html</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>en<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>head</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>meta</span> <span class="token attr-name">charset</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>UTF-8<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>title</span><span class="token punctuation">></span></span>register<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>title</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>head</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>body</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h1</span><span class="token punctuation">></span></span>register<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h1</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>form</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>formItem<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
    用户名:<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>username<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>br</span><span class="token punctuation">></span></span>
    密码:<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>password<span class="token punctuation">"</span></span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>password<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>br</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>form</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>btn<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>提交<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>body</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span><span class="token punctuation">></span></span><span class="token script language-javascript">
    document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">"#btn"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"click"</span><span class="token punctuation">,</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">let</span> formItem <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">"#formItem"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
        <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> el <span class="token keyword">of</span> formItem<span class="token punctuation">.</span>children<span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span>el<span class="token punctuation">.</span><span class="token function">hasAttribute</span><span class="token punctuation">(</span><span class="token string">"name"</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
                user<span class="token punctuation">[</span>el<span class="token punctuation">.</span><span class="token function">getAttribute</span><span class="token punctuation">(</span><span class="token string">"name"</span><span class="token punctuation">)</span><span class="token punctuation">]</span> <span class="token operator">=</span> el<span class="token punctuation">.</span>value<span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
        <span class="token punctuation">}</span>

        <span class="token keyword">let</span> result <span class="token operator">=</span> <span class="token function">sendHttp</span><span class="token punctuation">(</span><span class="token string">"/register"</span><span class="token punctuation">,</span><span class="token string">"POST"</span><span class="token punctuation">,</span>user<span class="token punctuation">,</span><span class="token keyword">function</span> <span class="token punctuation">(</span>result<span class="token punctuation">)</span> <span class="token punctuation">{</span>
            console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>js/sentHttp.js<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token script language-javascript"></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>html</span><span class="token punctuation">></span></span></code></pre>
<p>page1.html</p>
<pre class=" language-html"><code class="language-html"><span class="token doctype">&lt;!DOCTYPE html></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>html</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>en<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>head</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>meta</span> <span class="token attr-name">charset</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>UTF-8<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>title</span><span class="token punctuation">></span></span>page1<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>title</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>head</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>body</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h1</span><span class="token punctuation">></span></span>page1<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h1</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>body</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>html</span><span class="token punctuation">></span></span></code></pre>
<ul>
<li><strong><u>测试</u></strong></li>
</ul>
<p>在未登录的状态下点击page1，成功得到设置的结果</p>
<p><img src="https://s6.jpg.cm/2022/02/12/L4AVtC.png"></p>
<p>先进行登录</p>
<p><img src="https://s6.jpg.cm/2022/02/12/L4A80t.png"></p>
<p>再访问page1，成功的到达page1.html，注意，这里没有进行跳转，是将得到的结果重新覆盖主页</p>
<p>访问需要权限的接口**/test/admin**</p>
<p><img src="https://s6.jpg.cm/2022/02/12/L4AXLR.png"></p>
<p><img src="https://s6.jpg.cm/2022/02/12/L4AcUz.png"></p>
<p>后台抛出异常，这是因为登录的用户没有对应的权限，并且这个异常没有被<strong>AjaxAccessDeniedHandler</strong>处理，这里有点问题，需要进一步<strong>做统一异常处理</strong></p>
<h2 id="结语"><a href="#结语" class="headerlink" title="结语"></a>结语</h2><p>目前处于初学阶段，对于springsecurity+jwt的使用也不太熟练，理解也不深，对于之后整合<strong>oauth2</strong>及单点登录需要水平在高一些再做</p>

  </article>

  
      
    <div class="nexmoe-post-copyright">
        <strong>本文作者：</strong>塔纳托斯<br>
        <strong>本文链接：</strong><a href="http://hai-chao.gitee.io/blog/2022/02/12/27.springboot-ji-cheng-an-quan-kuang-jia/" title="http:&#x2F;&#x2F;hai-chao.gitee.io&#x2F;blog&#x2F;2022&#x2F;02&#x2F;12&#x2F;27.springboot-ji-cheng-an-quan-kuang-jia&#x2F;" target="_blank" rel="noopener">http:&#x2F;&#x2F;hai-chao.gitee.io&#x2F;blog&#x2F;2022&#x2F;02&#x2F;12&#x2F;27.springboot-ji-cheng-an-quan-kuang-jia&#x2F;</a><br>
        
            <strong>版权声明：</strong>本文采用 <a href="https://creativecommons.org/licenses/by-nc-sa/3.0/cn/deed.zh" target="_blank">CC BY-NC-SA 3.0 CN</a> 协议进行许可
        
    </div>


  
  
  <div class="nexmoe-post-meta nexmoe-rainbow">
    
    
        <a class="nexmoefont icon-tag-fill -none-link" href="/blog/tags/%E5%AD%A6%E4%B9%A0/" rel="tag">学习</a>
    
</div>

  
      <div class="nexmoe-post-footer">
          
      </div>
  
</div>
            <div class="nexmoe-post-right">
              <div class="nexmoe-fixed">
                  <div class="nexmoe-tool"> 
                    
                      
                        
                          
                          
                              <button class="mdui-fab catalog" style="overflow:unset;">
                                  <i class="nexmoefont icon-i-catalog"></i>
                                  <div class="nexmoe-toc">
                                      <ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#shiro"><span class="toc-number">1.</span> <span class="toc-text">shiro</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%83%BD%E5%B9%B2%E5%95%A5"><span class="toc-number">1.1.</span> <span class="toc-text">能干啥</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%A0%B8%E5%BF%83"><span class="toc-number">1.2.</span> <span class="toc-text">核心</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%9B%86%E6%88%90"><span class="toc-number">1.3.</span> <span class="toc-text">集成</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#spring-security"><span class="toc-number">2.</span> <span class="toc-text">spring security</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%83%BD%E5%B9%B2%E5%95%A5-1"><span class="toc-number">2.1.</span> <span class="toc-text">能干啥</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%9B%86%E6%88%90-1"><span class="toc-number">2.2.</span> <span class="toc-text">集成</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%A7%92%E8%89%B2%E7%BB%A7%E6%89%BF"><span class="toc-number">2.3.</span> <span class="toc-text">角色继承</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#jwt"><span class="toc-number">3.</span> <span class="toc-text">jwt</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#jwt%E7%9A%84%E4%BB%8B%E7%BB%8D"><span class="toc-number">3.1.</span> <span class="toc-text">jwt的介绍</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#jwt%E7%9A%84%E7%BB%84%E6%88%90"><span class="toc-number">3.2.</span> <span class="toc-text">jwt的组成</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%BB%83%E4%B9%A0"><span class="toc-number">3.3.</span> <span class="toc-text">练习</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#springsecurity-jwt"><span class="toc-number">4.</span> <span class="toc-text">springsecurity + jwt</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%BB%93%E8%AF%AD"><span class="toc-number">5.</span> <span class="toc-text">结语</span></a></li></ol>
                                  </div>
                              </button>
                          
                          
                      
                    
                      <a href="#nexmoe-content" class="toc-link" aria-label="回到顶部" title="top"><button class="mdui-fab mdui-ripple"><i class="nexmoefont icon-caret-top"></i></button></a>
                  </div>
              </div>
            </div>
        </div>
    </div>
    
    <script src="https://cdn.jsdelivr.net/combine/npm/lazysizes@5.1.0/lazysizes.min.js,npm/mdui@0.4.3/dist/js/mdui.min.js?v=1"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.js"></script>

 

<script async src="/blog/js/app.js?v=1679297521090"></script>



<script src="https://cdn.jsdelivr.net/npm/justifiedGallery@3.8.1/dist/js/jquery.justifiedGallery.min.js"></script>
<script>
	$(".justified-gallery").justifiedGallery({
		rowHeight: 160,
		margins: 10,
	});
</script>


    





</body>

</html>
